<!DOCTYPE html>
<html>
<head>
<title>Physics Diagram Reproduction</title>
<style>
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        background-color: #f0f0f0;
    }
    canvas {
        background-color: white;
        border: 1px solid #ccc;
    }
</style>
</head>
<body>
<canvas id="myCanvas" width="500" height="450"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// --- Helper Functions ---

function drawArrow(ctx, fromx, fromy, tox, toy) {
    const headlen = 10;
    const dx = tox - fromx;
    const dy = toy - fromy;
    const angle = Math.atan2(dy, dx);
    ctx.beginPath();
    ctx.moveTo(fromx, fromy);
    ctx.lineTo(tox, toy);
    ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
    ctx.moveTo(tox, toy);
    ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
    ctx.stroke();
}

function drawFrameSegment(ctx, p1, p2) {
    ctx.save();
    ctx.beginPath();
    ctx.moveTo(p1.x, p1.y);
    ctx.lineTo(p2.x, p2.y);
    ctx.strokeStyle = '#999'; // Gray color
    ctx.lineWidth = 6;
    ctx.lineCap = 'round';
    ctx.stroke();
    ctx.beginPath();
    ctx.moveTo(p1.x, p1.y);
    ctx.lineTo(p2.x, p2.y);
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 2;
    ctx.stroke();
    ctx.restore();
}

function drawDisk(ctx, p1, p2, rotationDir) {
    const cx = (p1.x + p2.x) / 2;
    const cy = (p1.y + p2.y) / 2;
    const segAngle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
    const ellipseRotation = segAngle + Math.PI / 2;

    const diskRadius = 25;
    const diskThicknessRadius = 8;
    const hubRadius = 6;
    const hubThicknessRadius = 2;

    // Axle (drawn behind disk)
    ctx.save();
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 4;
    ctx.beginPath();
    const axleExtension = 20;
    ctx.moveTo(cx - axleExtension * Math.cos(segAngle), cy - axleExtension * Math.sin(segAngle));
    ctx.lineTo(cx + axleExtension * Math.cos(segAngle), cy + axleExtension * Math.sin(segAngle));
    ctx.stroke();
    ctx.restore();
    
    // Disk
    ctx.save();
    ctx.fillStyle = 'white';
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.ellipse(cx, cy, diskThicknessRadius, diskRadius, ellipseRotation, 0, 2 * Math.PI);
    ctx.fill();
    ctx.stroke();
    
    // Hub
    ctx.beginPath();
    ctx.ellipse(cx, cy, hubThicknessRadius, hubRadius, ellipseRotation, 0, 2 * Math.PI);
    ctx.stroke();
    ctx.restore();

    // Rotation Arrow
    ctx.save();
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 1.5;
    const isCW = rotationDir === 'cw';
    const arrowStartAngle = isCW ? Math.PI * 1.4 : -Math.PI * 0.4;
    const arrowEndAngle = isCW ? Math.PI * 0.6 : Math.PI * 0.4;
    
    ctx.beginPath();
    ctx.ellipse(cx, cy, diskThicknessRadius * 0.7, diskRadius * 0.7, ellipseRotation, arrowStartAngle, arrowEndAngle, isCW);
    ctx.stroke();

    // Arrowhead
    const headPoint = isCW ? 
        {angle: arrowEndAngle, dir: -1} : 
        {angle: arrowEndAngle, dir: 1};
    
    // Get endpoint of arc in ellipse's coordinate system
    let endX_local = diskThicknessRadius * 0.7 * Math.cos(headPoint.angle);
    let endY_local = diskRadius * 0.7 * Math.sin(headPoint.angle);

    // Rotate to global system
    let endX = cx + endX_local * Math.cos(ellipseRotation) - endY_local * Math.sin(ellipseRotation);
    let endY = cy + endX_local * Math.sin(ellipseRotation) + endY_local * Math.cos(ellipseRotation);
    
    // Get tangent direction (approximated)
    const tangentAngle = ellipseRotation + headPoint.angle + Math.PI/2;
    
    const headLen = 6;
    ctx.beginPath();
    ctx.moveTo(endX, endY);
    ctx.lineTo(endX - headLen * Math.cos(tangentAngle - headPoint.dir * Math.PI / 6), endY - headLen * Math.sin(tangentAngle - headPoint.dir * Math.PI / 6));
    ctx.moveTo(endX, endY);
    ctx.lineTo(endX - headLen * Math.cos(tangentAngle + headPoint.dir * Math.PI / 6), endY - headLen * Math.sin(tangentAngle + headPoint.dir * Math.PI / 6));
    ctx.stroke();
    ctx.restore();
}

// --- Main Drawing ---

// Coordinates
const O = { x: 90, y: 220 };
const C1 = { x: 230, y: 160 }; // Top vertex
const C2 = { x: 370, y: 220 }; // Right vertex
const C3 = { x: 230, y: 280 }; // Bottom vertex

// Draw Frame
drawFrameSegment(ctx, O, C1);
drawFrameSegment(ctx, C1, C2);
drawFrameSegment(ctx, C2, C3);
drawFrameSegment(ctx, C3, O);

// Draw Disks
drawDisk(ctx, O, C1, 'ccw');
drawDisk(ctx, C1, C2, 'cw');
drawDisk(ctx, C2, C3, 'ccw');
drawDisk(ctx, C3, O, 'cw');

// Draw Pivot Support at O
ctx.save();
ctx.lineWidth = 3;
ctx.strokeStyle = 'black';
ctx.beginPath();
ctx.moveTo(O.x, O.y);
ctx.lineTo(O.x - 10, O.y);
ctx.moveTo(O.x - 10, O.y + 10);
ctx.lineTo(O.x - 10, O.y + 35);
ctx.stroke();
// Rope texture
ctx.lineWidth = 1;
for (let i = 0; i < 5; i++) {
    ctx.beginPath();
    ctx.moveTo(O.x - 15, O.y + 10 + i * 5);
    ctx.lineTo(O.x - 5, O.y + 15 + i * 5);
    ctx.stroke();
}
ctx.restore();

// Draw Force and Construction Lines
const P_force = C3;
const C_construct = { x: P_force.x, y: O.y }; 

ctx.save();
ctx.strokeStyle = 'black';
ctx.lineWidth = 1.5;
ctx.setLineDash([4, 4]);
ctx.beginPath();
ctx.moveTo(P_force.x, P_force.y);
ctx.lineTo(C_construct.x, C_construct.y); // Vertical line
ctx.stroke();
ctx.beginPath();
ctx.moveTo(O.x, O.y);
ctx.lineTo(C_construct.x, C_construct.y); // Horizontal line
ctx.stroke();
ctx.restore();

// Draw right angle symbol at C
ctx.save();
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(C_construct.x, C_construct.y - 8);
ctx.lineTo(C_construct.x - 8, C_construct.y - 8);
ctx.lineTo(C_construct.x - 8, C_construct.y);
ctx.stroke();
ctx.restore();

// Force arrow
const forceStart = P_force;
const forceEnd = { x: forceStart.x, y: forceStart.y + 70 };
ctx.save();
ctx.lineWidth = 2.5;
drawArrow(ctx, forceStart.x, forceStart.y, forceEnd.x, forceEnd.y);
ctx.restore();

// Draw Labels
ctx.font = 'bold 20px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('O', O.x - 20, O.y);
ctx.fillText('C', C_construct.x + 15, C_construct.y - 15);
ctx.font = 'italic 20px serif';
ctx.fillText('4mg', forceEnd.x + 35, forceEnd.y - 25);

// Dimension D
const D_y_level = C3.y + 60;
const D_start_x = C1.x;
const D_end_x = C2.x;
ctx.save();
ctx.lineWidth = 1;
ctx.setLineDash([2, 2]);
ctx.beginPath();
ctx.moveTo(C1.x, C1.y);
ctx.lineTo(D_start_x, D_y_level);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(C2.x, C2.y);
ctx.lineTo(D_end_x, D_y_level);
ctx.stroke();
ctx.setLineDash([]);
ctx.beginPath();
ctx.moveTo(D_start_x, D_y_level);
ctx.lineTo(D_end_x, D_y_level);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(D_start_x, D_y_level - 5);
ctx.lineTo(D_start_x, D_y_level + 5);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(D_end_x, D_y_level - 5);
ctx.lineTo(D_end_x, D_y_level + 5);
ctx.stroke();
ctx.restore();
ctx.font = 'italic 22px serif';
ctx.fillText('D', (D_start_x + D_end_x) / 2, D_y_level + 20);

// Figure caption
ctx.font = '18px sans-serif';
ctx.fillStyle = 'black';
ctx.fillText('Fig. 1.183.', canvas.width / 2, 430);

</script>
</body>
</html>